﻿#include <ClassDataBase.h>
#include <QMetaProperty>
#include <iostream>
#include <EDesignerCore.h>//bug，这里迫于propertymanager的使用方式，只能把本类和核心类耦合起来了。
#include <PropertyEditorWindow.h>
#include <QStringList>
#include <EObject.h>
ClassDataBase::ClassDataBase()
{

}

ClassDataBase::~ClassDataBase()
{

}
void ClassDataBase::registClassDataList(QSharedPointer<QObject> object_ptr)
{
    const QMetaObject *metaobject = object_ptr->metaObject();
    const QMetaObject* current_object = metaobject;
    //检查已经注册的类中有没有
    if (checkClassTypeInList(metaobject->className()) == true)
    {
        return;
    }
    else
    {
        //注册类，但不包含父类
        registClassData(current_object, object_ptr.data());
    }
    /*处理父类*/
    while (QString(current_object->className()) != "EObject")
    {
        current_object = current_object->superClass();
        if (checkClassTypeInList(current_object->className()) == true)
        {
            continue;
        }
        else
        {
            //注册类，但不包含父类
            registClassData(current_object, object_ptr.data());
        }
    }

}

void ClassDataBase::registClassData(const QMetaObject* object_ptr , QObject *qobj)
{
    // 这里要完成两个任务，一个是生成property，一个是要将新的ClassData放到List里面
    const QMetaObject *metaobject = object_ptr;

    QSharedPointer<ClassData> class_data(new ClassData);
    m_classDataList.push_back(class_data);
    class_data->setClassTypeName(metaobject->className());

    QVariant showInClassListVariant = qobj->property("ShowInClassList");
    if(showInClassListVariant.isValid())
    {
        class_data->setShowInClassList(showInClassListVariant.toBool());
    }

    //增加属性
    QtVariantPropertyManager* property_manager = EDesignerCore::instance()->propertyEditorWindow()->getPropertyEditor()->getPropertyManager();
    QtVariantPropertyManager* property_manager_read_only = EDesignerCore::instance()->propertyEditorWindow()->getPropertyEditor()->getPropertyManagerReadOnly();
    QtVariantProperty *group_priority = property_manager->addProperty(property_manager->groupTypeId(), metaobject->className());
    for (int i=metaobject->propertyOffset(); i < metaobject->propertyCount(); ++i)
    {
        QMetaProperty metaproperty = metaobject->property(i);
        const char *name = metaproperty.name();
        QString property_name(name);//属性名
        QString type_name(metaproperty.typeName());//类型名
        //std::cout<<"ClassDataBase::registClassData"<<property_name.toStdString()<<"="<<metaproperty.type()<<std::endl;
        if(metaproperty.isEnumType())
        {
            QtVariantProperty* property_temp;
            if(metaproperty.isWritable() == true)
            {
                property_temp = property_manager->addProperty(QtVariantPropertyManager::enumTypeId(), property_name);
            }
            else
            {
                property_temp = property_manager_read_only->addProperty(QtVariantPropertyManager::enumTypeId(), property_name);
            }
            /**/
            QStringList enumStrList;
            QMetaEnum metaEnum = metaproperty.enumerator();
            for(int j = 0; j < metaEnum.keyCount(); j++)
            {

                QString strValue(metaEnum.key(j));
                //std::cout<<"ClassDataBase::registClassData enumKey  "<<strValue.toStdString()<<std::endl;
                //enumStrList<<strValue;
                enumStrList.push_back(strValue);
            }

            property_temp->setAttribute("enumNames", enumStrList);
            //property_temp->setValue(0);
            group_priority->addSubProperty(property_temp);
        }
        else
        {
            QtVariantProperty* property_temp;
            if(metaproperty.isWritable() == true)
            {
                property_temp = property_manager->addProperty(metaproperty.type(), property_name);
            }
            else
            {
                property_temp = property_manager_read_only->addProperty(metaproperty.type(), property_name);
            }
            group_priority->addSubProperty(property_temp);

            //double 小数位设置
            //            if(metaproperty.type() == QVariant::Type::)
            //            {

            //            }
        }


    }
    class_data->setVariantProperty(group_priority);
}
QList<QSharedPointer<ClassData>> ClassDataBase::getClassDataList(QSharedPointer<QObject> object_ptr)
{
    QList<QSharedPointer<ClassData>> class_data_list;
    const QMetaObject *metaobject = object_ptr->metaObject();
    const QMetaObject* current_object = metaobject;
    //检查已经注册的类中有没有
    if (checkClassTypeInList(current_object->className()) == false)
    {
        return class_data_list;
    }
    else
    {
        class_data_list.push_front(getClassData(current_object));
        getClassData(current_object)->fillPropertyValue(object_ptr);
    }
    /*处理父类*/
    while (QString(current_object->className()) != "QObject")
    {
        current_object = current_object->superClass();
        if (checkClassTypeInList(current_object->className()) == false)
        {
            continue;
        }
        else
        {
            class_data_list.push_front(getClassData(current_object));
            getClassData(current_object)->fillPropertyValue(object_ptr);
        }
    }
    return class_data_list;
}

QList<QSharedPointer<ClassData> > ClassDataBase::getClassDataListAll()
{
    return m_classDataList;
}

QList<QSharedPointer<ClassData>> ClassDataBase::setCurrentObject(QSharedPointer<QObject> object_ptr)
{
    m_currentObject = object_ptr;
    m_currentClassDataList = getClassDataList(object_ptr);
    return m_currentClassDataList;
}

void ClassDataBase::uiPropertyValueChanged( QtProperty * property, const QVariant & value )
{
    /**/
    EObject* eObjPtr = dynamic_cast<EObject*>(m_currentObject.data());
    if(eObjPtr != NULL)
    {
        QString property_name = property->propertyName();
        if(m_currentObject->property(property_name.toStdString().c_str()) != value)
        {
            m_currentObject->setProperty(property_name.toStdString().c_str(), value);
            QVariant new_value = m_currentObject->property(property_name.toStdString().c_str());
            QtVariantProperty* variant_property = dynamic_cast<QtVariantProperty*>(property);
            if(variant_property != NULL && new_value != value)
            {
                variant_property->setValue(new_value);
            }
        }
    }

}

QSharedPointer<ClassData> ClassDataBase::getClassData( const QMetaObject* object_ptr )
{
    //bug,这里可以优化
    QSharedPointer<ClassData> class_data_ptr;
    for (int i=0; i < m_classDataList.size(); i ++)
    {
        if (m_classDataList.at(i)->getClassTypeName() == object_ptr->className())
        {
            class_data_ptr = m_classDataList.at(i);
            break;
        }
    }
    return class_data_ptr;
}

bool ClassDataBase::checkClassTypeInList(const QString& class_type_str)
{
    //bug,这里可以优化
    bool result= false;
    for (int i=0; i < m_classDataList.size(); i ++)
    {
        if (m_classDataList.at(i)->getClassTypeName() == class_type_str)
        {
            result = true;
            break;
        }
    }
    return result;
}

int ClassDataBase::getQVariantType( const QString& type_name )
{
    if (type_name == "QString")
    {
        return QVariant::String;
    }
    else
    {
        return QVariant::Int;
    }
}

QList<int> ClassDataBase::getSuperClassPropertyOffsetList(QMetaObject *metaobject)
{
    QList<int> offset_list;
    if (metaobject == NULL)
    {
        return offset_list;
    }
    const QMetaObject* current_object = metaobject;
    while (current_object->className() != "QObject")
    {
        offset_list.push_back(current_object->propertyOffset());
        current_object = current_object->superClass();
    }
    return offset_list;
}

